package ca.etsmtl.log120.tp1.io;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Observable;
import java.util.Observer;

/******************************************************
Cours : LOG120
Session : E2011
Groupe : 01
Projet : Laboratoire #1
Etudiants : Nicolas Blais Miko
 	 		Yohan Trepanier-Montpetit
Codes perm. : BLAN24079109
			  TREY19079108
Professeur : Chamseddine Talhi
Charge de labo : Eric Goulet
Nom du fichier : SocketCom.java
Date cree : 2011-05-15
Date dern. modif. 2015-05-15
*************************************************** ****
Historique des modifications
*************************************************** ****
2011-05-15 Version initiale (Yohan Trepanier)
***************************************************/

/**
 * Classe qui gere la connection et la communication reseau
 * @author Yohan
 *
 */
public class SocketCom extends Observable implements Observer{

	private Socket socket; 	//Le socket a utiliser
	SocketReader reader; 	//Le lecteur d'info
	PrintWriter out;		//Le outputStream du socket
	
	/**
	 * Methode permettant de se connecter a une adresse et a un port donnes
	 */
	public void connect(String address, int port) throws UnknownHostException,IOException,IllegalArgumentException{
		
		//Ouverture du socket
		
			socket = new Socket(address,port);

		//Mise en memoire de la sortie du socket
		try {
			out = new PrintWriter(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		//Instance du lecteur socket
		reader = new SocketReader(socket);

		//Creation et demarrage du thread
		Thread readThread = new Thread(reader);
		readThread.start();

		//Abonnement aux receptions de message du reader
		reader.addObserver(this);
	}

	/**
	 * Fermeture de la connection
	 */
	public void close(){
	
		try{
			send("END"); //envoi du message
			reader.endThread(); //fin de la lecture
		}catch(NullPointerException ex){ex.printStackTrace();}
			
		//attente pour eviter plantage si le reseau est lent
		try {
			Thread.sleep(200);
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		}
		
		//fermeture du socket
		try {
			socket.close();
		} catch (IOException e) {

			e.printStackTrace();
		}catch(NullPointerException ex2){ex2.printStackTrace();}
	}

	/**
	 * Acceder au dernier message recuisClosed
	 * @return le dernier message
	 */
	public String getMessage(){

		return reader.getLastString();
	}

	/**
	 * Envoyer une commande
	 * @param cmd La commande a envoyer
	 */
	public void send(String cmd){
		
//		System.out.println("SocketCom: send: " + cmd);
		
		//envoie de la commande par le printer du socket
		if(socket != null){
			out.print(cmd + '\n');
			out.flush();	
		}
	}
	
	/**
	 * Methode qui verifie si la connexion avec le serveur est fermee
	 * @return True si aucune connexion n'est ouverte, False sinon
	 */
	public boolean isClosed(){
		
		boolean connexionFerme; //Variable pour savoir si la connexion est fermee
		
		try{
			connexionFerme = socket.isClosed(); //On verifie si la connexion est fermee
		}catch(NullPointerException e){
			
			connexionFerme = true; //Si la connexion n'a jamais ete ouverte, on veut retourner true
		}
		
		return connexionFerme;
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		//Lorsqu'on recoit de l'info, on l'affiche et on notifie les amis
//		System.out.print("SocketCom: New message: " + getMessage());
		setChanged();
		notifyObservers();

	}	


}

